package mainPackage;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;

import objects.*;

public class GameWindow extends JFrame implements ActionListener, KeyListener,
		MouseListener {
	
	Dimension screenSize;
	Dimension windowSize = new Dimension(800, 600);
	boolean fullscreen = false;
	boolean running = true;
	
	BufferedImage bufferImage;
	Graphics2D bufferedGraphics2d;
	Color backgroundColor;
	
	CollisionMap collisionMap;
	Map map;
	Ball ball;

	double wind = 0.0;
	double gravitation = 0.0;

	int[] buttonExit = new int[4];

	public GameWindow() {
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		screenSize = toolkit.getScreenSize();
		setup();
		update();
	}

	void setup() {
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setLayout(null);
		this.setBackground(Color.blue);
		//this.setResizable(false);
		if(fullscreen){
			windowSize = screenSize;
			this.setLocation(0, 0);
			this.setUndecorated(true);
			GraphicsDevice device;
			device = GraphicsEnvironment.getLocalGraphicsEnvironment()
					.getScreenDevices()[0];
			device.setFullScreenWindow(this);
		}else{
			this.setLocation(100, 50);
			this.setUndecorated(false);
			this.setSize(windowSize);
		}
		
		addMouseListener(this);
		addKeyListener(this);
		this.addComponentListener(new java.awt.event.ComponentAdapter() 
		{
			public void componentResized(ComponentEvent e)
			{
				bufferImage = new BufferedImage(windowSize.width, windowSize.height, BufferedImage.TYPE_INT_ARGB);
				bufferedGraphics2d = (Graphics2D)bufferImage.getGraphics();
				bufferedGraphics2d.setColor(backgroundColor);
				bufferedGraphics2d.fillRect(0, 0, windowSize.width, windowSize.height);
			}
		});
		
		collisionMap = new CollisionMap(windowSize);
		map = new Map(windowSize, collisionMap);
		backgroundColor = new Color(0, 0, 200);
		bufferImage = new BufferedImage(windowSize.width, windowSize.height, BufferedImage.TYPE_INT_ARGB);
		bufferedGraphics2d = (Graphics2D)bufferImage.getGraphics();
		bufferedGraphics2d.setColor(backgroundColor);
		bufferedGraphics2d.fillRect(0, 0, windowSize.width, windowSize.height);
		
		ball = new Ball((windowSize.width - 50) * Math.random(), (windowSize.height - 50) * Math.random(),
				10 * (Math.random() - 0.5), 10 * (Math.random() - 0.5), 10, Color.red);
		
		buttonExit[0] = 20;
		buttonExit[1] = 20;
		buttonExit[2] = 30;
		buttonExit[3] = 20;
		
		this.setVisible(true);
	}

	void update() {
		
		windowSize.width = this.getWidth();
		windowSize.height = this.getHeight();
		
		if(running){
			
			ball.setySpeed(ball.getySpeed() + gravitation);
			ball.setySpeed(ball.getySpeed() * 0.99);
			ball.setxSpeed(ball.getxSpeed() + wind);
			ball.setxSpeed(ball.getxSpeed() * 0.99);
			ball.move(windowSize);
			collisionMap.checkCollision(ball);
	
			paint(this.getGraphics());
			
		}
		try {
			Thread.sleep(20);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		update();
		
	}

	public void paint(Graphics g) {
		bufferedGraphics2d = (Graphics2D)bufferImage.getGraphics();
		
		map.paint(bufferedGraphics2d);
		ball.paint(bufferedGraphics2d);
		
		if(fullscreen){
			bufferedGraphics2d.setColor(Color.red);
			bufferedGraphics2d.fillRect(buttonExit[0], buttonExit[1], buttonExit[2], buttonExit[3]);
			bufferedGraphics2d.setColor(Color.black);
			bufferedGraphics2d.drawRect(buttonExit[0], buttonExit[1], buttonExit[2], buttonExit[3]);
		}
		
		g.drawImage(bufferImage, 0, 0, null);
		
		ball.clear(bufferedGraphics2d, backgroundColor);
	}

	@Override
	public void mouseClicked(MouseEvent arg0) {
		if (fullscreen 
				&& arg0.getPoint().x >= buttonExit[0]
				&& arg0.getPoint().x <= buttonExit[0] + buttonExit[2]
				&& arg0.getPoint().y >= buttonExit[1]
				&& arg0.getPoint().y <= buttonExit[1] + buttonExit[3]) {
			System.exit(0);
		} else {
			ball.setxPos(arg0.getPoint().x);
			ball.setyPos(arg0.getPoint().y);
			bufferedGraphics2d = (Graphics2D)bufferImage.getGraphics();
			bufferedGraphics2d.setColor(backgroundColor);
			bufferedGraphics2d.fillRect(0, 0, windowSize.width, windowSize.height);
			
			collisionMap.checkCollision(ball);
			paint(this.getGraphics());
		}
	}

	@Override
	public void mouseEntered(MouseEvent arg0) {

	}

	@Override
	public void mouseExited(MouseEvent arg0) {

	}

	@Override
	public void mousePressed(MouseEvent arg0) {

	}

	@Override
	public void mouseReleased(MouseEvent arg0) {

	}

	@Override
	public void keyPressed(KeyEvent arg0) {
		int keyCode = arg0.getKeyCode();
		switch (keyCode) {
		case KeyEvent.VK_UP:
			if(arg0.isShiftDown())
				gravitation -= 0.1;
			else 
				ball.setySpeed(ball.getySpeed() - 10);
			break;
		case KeyEvent.VK_DOWN:
			if(arg0.isShiftDown())
				gravitation += 0.1;
			else
				ball.setySpeed(ball.getySpeed() + 10);
			break;
		case KeyEvent.VK_LEFT:
			if(arg0.isShiftDown())
				wind -= 0.1;
			else
				ball.setxSpeed(ball.getxSpeed() - 10);
			break;
		case KeyEvent.VK_RIGHT:
			if(arg0.isShiftDown())
				wind += 0.1;
			else
				ball.setxSpeed(ball.getxSpeed() + 10);
			break;
		case KeyEvent.VK_SPACE:
			if(arg0.isShiftDown()){
				wind = 0;
				gravitation = 0;
			}else{
				ball.setxSpeed(0);
				ball.setySpeed(0);
			}
			break;
		case KeyEvent.VK_P:
			running = !running;
			break;
		}
	}

	@Override
	public void keyReleased(KeyEvent arg0) {

	}

	@Override
	public void keyTyped(KeyEvent arg0) {

	}

	@Override
	public void actionPerformed(ActionEvent e) {

	}

	public CollisionMap getCollisionMap() {
		return collisionMap;
	}

}
